import { _decorator, Component, Node, AudioClip, AudioSource, assert, macro, find } from 'cc';
const { ccclass, property } = _decorator;

interface IAudioClip {
	[name: string]: AudioClip;
}

@ccclass("CommonAudioManager")
export class CommonAudioManager extends Component {
	@property([AudioClip])
	public audioClips: AudioClip[] = [];

	private _clipDict: IAudioClip = {};
	private _audioSource: AudioSource = null!;

	private _audioList: { as: AudioSource, name: string }[] = [];

	private _mute: boolean = false;
	start() {
		// 将音频资源存起来
		new AudioContext().resume();
		for (let i = 0; i < this.audioClips.length; i++) {
			let element = this.audioClips[i];
			this._clipDict[element.name] = element;
		}
		this._audioSource = this.getComponent(AudioSource);
		let self = this;
		window.addEventListener("ccc:muteAll", function () {
			self.muteAll();
		});
		window.addEventListener("ccc:unmute", function () {
			self.resume();
		});
	}

	/**
	 * @def 音效.只播放一次
	 * @param name 音频名,不用加后缀
	 */
	public play(name: string, volumeScale?: number) {
		if (this._mute) return;
		const clip = this._clipDict[name];
		volumeScale = volumeScale ?? 1;
		if (clip !== undefined) {
			this._audioSource.playOneShot(clip, volumeScale);
		}
	}

	public muteAll() {
		this.stopPlay();
		this._mute = true;
	}

	resume() {
		this._mute = false;
	}

	/**
	 * @def 音乐.循环播放
	 * @param name 音频名,不用加后缀
	 * @param volume 播发音量
	 */
	public loopPlay(name: string, volume?: number) {
		if (this._mute) return;
		const clip = this._clipDict[name];
		if (clip !== undefined) {
			this._audioSource.loop = true;
			this._audioSource.clip = clip;
			if (volume) {
				this._audioSource.volume = volume;
			}
			if (!this._audioSource.playing) {
				this._audioSource.play();
			}
			// setTimeout(() => {
			// 	this._audioSource.play();
			// }, 100);
		}
	}

	/**
	 * @def 暂停播放当前音乐(音效)
	 */
	public pauseCurrentPlay() {
		this.node.getComponent(AudioSource).pause();
	}

	public stopPlay() {
		this.node.getComponent(AudioSource).stop();
	}

	/**
	 * 得到某音频播放时长
	 * @param name 
	 * @returns 
	 */
	public getSoundTime(name: string) {
		const clip = this._clipDict[name]
		return clip.getDuration()
	}

	createAudioNum: number = 0
	/**
	 * 循环播放音效
	 * @param name 音效名
	 * @param volume 声音大小
	 * @returns 
	 */
	public playLoopFx(name: string, volume: number = 1) {
		if (this._mute) return;
		if (!this._clipDict[name]) return console.error(`不存在音频${name}`)
		//先判断是否有空闲的音频
		let createAuidoNodeFunc = () => {
			if (this._audioList.length >= 5) return console.log("限制最多6个同时播放的音效")
			this.createAudioNum++
			let node = new Node("AS" + this.createAudioNum)
			node.setParent(this.node)
			const clip = this._clipDict[name];
			let as = node.addComponent(AudioSource)
			this._audioList.push({ as: as, name: name })
			as.loop = true;
			as.clip = clip;
			if (volume >= 0) {
				as.volume = volume;
			}
		}

		new Promise((resolve, reject) => {
			if (this._audioList.length > 0) {
				for (let i = 0; i < this._audioList.length; i++) {
					let obj = this._audioList[i];
					if (!obj.name) {	//不存在名字代表空闲
						let as = obj.as
						as.loop = true;
						const clip = this._clipDict[name];
						as.clip = clip;
						obj.name = name
						as.play()
						if (volume >= 0) {
							as.volume = volume;
						}
						return
					}
					if (i == this._audioList.length - 1) {
						resolve(1)
					}
				}
			} else {
				resolve(1)
			}
		}).then(() => {
			createAuidoNodeFunc()
		})
	}

	/**
	 * 停止循环播放音效
	 * @param name 
	 */
	public stopLoopFx(name: string) {
		for (let i = 0; i < this._audioList.length; i++) {
			let obj = this._audioList[i];
			if (obj.name == name) {	//不存在名字代表空闲
				this._audioList[i].name = ""
				this._audioList[i].as.loop = false
				this._audioList[i].as.stop()
				return
			}
		}
	}
}

